#define   MODAIN
#include "StepByStep.h"

extern char *yytext;

void OpsError(int errno, char *Msg)
{
  ErrorNo = errno;
  strcpy(ErrorMsg, Msg);
}

int yywrap()
{
  return 1;
}

void yyerror()
{
  fflush(stdout);

  printf("Syntax error in line %d, '%s':\n", lineno, yytext);

  if (ErrorNo == NOFOUND) printf("No Error Message\n");
  else printf("%s %s\n", ErrMsg[ErrorNo], ErrorMsg);

  exit(ERROR);
}

void UpperFirstCharOfString(char *string)
{
  while (*string) {
    while (*string && !isalpha(*string)) string++;

    if (!*string) break;

    *string++ = (char)toupper(*string);
    while (*string && isalpha(*string))
      *string++ = (char)tolower(*string);
  }
}

char* RemoveSpaceAndTab(char *s)
{
  for (s++; (*s==' ' || *s=='\t'); s++) ;
  return s;
}

PENode* NewPENode(TypeOfNode Type)
{
  PENode *Pt = (PENode *) calloc(1, sizeof(PENode));
  Pt->Type = Type;
  return Pt;
}

StringList *CopyListOfType(StringList *Source)
{
  StringList *Dest, *Pt1, *Pt2, *Pt3;

  Dest = NULL;
  for (Pt1 = Source; Pt1 != NULL; Pt1 = Pt1->next) {
    Pt2 = (StringList *) calloc(1, sizeof(StringList));
    strcpy(Pt2->Name, Pt1->Name);

    if (Dest == NULL) Dest = Pt2;
    else Pt3->next = Pt2;

    Pt3 = Pt2;
  }

  return Dest;
}

void CopyValueList(ValueList *Dest, ValueList *Source)
{
  VList *Pt, *Pt1, *Pt2;

  FreeValueList(Dest);

  Pt1 = NULL;
  for (Pt2 = Source->List; Pt2 != NULL; Pt2 = Pt2->next) {
    Pt = (VList *) calloc(1, sizeof(VList));
    Pt->Idx = Pt2->Idx;

    if (Pt1 == NULL) Dest->List = Pt;
    else Pt1->next = Pt;

    Pt1 = Pt;
  }

  Dest->NumValue = Source->NumValue;
}

TokenList* CopyTokenList(TokenList *Pt)
{
  TokenList *Pt1, *Pt2, *Pt3;

  Pt1 = NULL;
  while (Pt != NULL) {
    Pt2 = (TokenList *) calloc(1, sizeof(TokenList));

    strcpy(Pt2->VList.Name, Pt->VList.Name);
    Pt2->VList.ParaIdx = Pt->VList.ParaIdx;
    CopyValueList(&(Pt2->VList), &(Pt->VList));

    if (Pt1 == NULL) Pt1 = Pt2;
    else Pt3->next = Pt2;

    Pt3 = Pt2;
    Pt = Pt->next;
  }

  return Pt1;
}

Bool CheckValueList(int Idx, ValueList *VL)
{
  VList *Pt;

  Pt = VL->List;
  while (Pt != NULL && Pt->Idx < Idx) Pt = Pt->next;

  return (Pt!=NULL && Pt->Idx==Idx);
}

void InsertOneValueIntoValueList(int Idx, ValueList *VL)
{
  VList *Pt1, *Pt2;

  Pt1 = NULL;
  for (Pt2 = VL->List; Pt2!=NULL && Pt2->Idx<Idx; Pt2 = Pt2->next) Pt1 = Pt2;

  if (Pt2 == NULL || Pt2->Idx != Idx) {
     Pt2 = (VList *) calloc(1, sizeof(VList));
     Pt2->Idx = Idx;

     VL->NumValue++;

     if (Pt1 == NULL) { Pt2->next = VL->List;  VL->List = Pt2; }
     else { Pt2->next = Pt1->next;  Pt1->next = Pt2; }
  }
}

void MergeTwoVLists(ValueList *Dest, ValueList *Source)
{
  VList *Pt;

  for (Pt = Source->List; Pt != NULL; Pt = Pt->next)
    InsertOneValueIntoValueList(Pt->Idx, Dest);
}

void CopyOneTypedList(TypedList *Dest, TypedList *Source)
{
  strcpy(Dest->VList.Name, Source->VList.Name);
  Dest->Type = CopyListOfType(Source->Type);
  Dest->VList.ParaIdx = Source->VList.ParaIdx;
  CopyValueList(&(Dest->VList), &(Source->VList));
}

TypedList* CopyTypedArray(int Num, TypedList *Pt)
{
  TypedList *Pt1, *Pt2;
  int        i;

  if (Num == 0) return NULL;

  Pt1 = Pt2 = (TypedList *) calloc(Num, sizeof(TypedList));
  for (i = 0; i < Num; i++,Pt++,Pt2++) CopyOneTypedList(Pt2, Pt);

  return Pt1;
}

Bool ValueListInValueList(ValueList *VL1, ValueList *VL2)
{
  VList *Pt1, *Pt2;

  if (VL1->NumValue > VL2->NumValue) return FALSE;

  Pt2 = VL2->List;
  for (Pt1 = VL1->List; Pt1 != NULL; Pt1 = Pt1->next) {
    while (Pt2!=NULL && Pt2->Idx<Pt1->Idx) Pt2 = Pt2->next;

    if (Pt2==NULL || Pt2->Idx!=Pt1->Idx) return FALSE;
  }

  return TRUE;
}

void DeleteOneValueFromValueList(int Value, ValueList *Dest)
{
  VList *Pt1, *Pt2;

  Pt1 = NULL;
  for (Pt2 = Dest->List; Pt2 != NULL; Pt1=Pt2,Pt2=Pt2->next)
    if (Value == Pt2->Idx) break;

  if (Pt1 == NULL) Dest->List = Pt2->next;
  else Pt1->next = Pt2->next;

  Dest->NumValue--;
  free(Pt2);
}

Bool EqualTwoVLists(ValueList *VL1, ValueList *VL2)
{
  VList *Pt1, *Pt2;

  if (VL1->NumValue != VL2->NumValue) return FALSE;

  Pt1 = VL1->List;
  Pt2 = VL2->List;
  while (Pt1!=NULL && Pt1->Idx==Pt2->Idx) Pt1=Pt1->next,Pt2=Pt2->next;

  return (Pt1==NULL);
}

Bool TypedListInTypedList(int Num, TypedList *P1, TypedList *P2)
{
  int i;

  for (i = 0; i < Num; i++,P1++,P2++)
    if (!ValueListInValueList(&(P2->VList), &(P1->VList)))
       return FALSE;

  return TRUE;
}

Bool EqualTwoPredications(PredKnowledge *Pd1, PredKnowledge *Pd2)
{
  TypedList *P1, *P2;
  int        i, Num;

  if (Pd1->Type!=Pd2->Type || Pd1->PredNo!=Pd2->PredNo) return FALSE;

  Num = NumParaOfPred(Pd1->PredNo);
  P1 = Pd1->Para;  P2 = Pd2->Para;
  for (i = 0; i < Num; i++,P1++,P2++)
    if (!EqualTwoVLists(&(P1->VList), &(P2->VList))) return FALSE;

  return TRUE;
}

Bool CheckTransform(int Num, int *Para, int j, int Idx)
{
  int i;

  for (i = 0; i < Num; i++)
    if (Para[i] == Idx) return FALSE;

  Para[j] = Idx;
  return TRUE;
}

Bool TypeInListOfType(char *Name, StringList *List)
{
  while (List != NULL) {
    if (IsSame(Name, List->Name)) return TRUE;
    List = List->next;
  }

  return FALSE;
}

